#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
using namespace std;
bool compare(map<int, int>::iterator x, map<int, int>::iterator y)
{
    return x->second < y->second;
}

struct books
{
    string name;
    float price;
    int amount;
};
bool operator<(const books &a, const books &b)
{
    return a.price > b.price; //重载<为降序排列
}
int main()
{
    // map<int>和map<int, int,int>是错误的，只能包含两个元素。map的构造方式和vector一样
    map<int, int> test1{{3, 11}};
    map<int, int> test2{pair<int, int>{3, 4}};
    map<int, int> test3{make_pair(5, 6)};
    map<string, int> test4{{"hello", 7}};

    // 访问map，迭代器进行下标访问
    for (auto iter = test1.begin(); iter != test1.end(); iter++) // iter类型为map<int, int>::iterator iter
    {
        cout << iter->first << endl;
    }
    cout << "============" << endl;
    // test1[i]通过key访问
    // map只能通过迭代器和key来访问，test1[i]不是访问第i个元素，而是key为i的元素
    for (size_t i = 0; i < test1.size(); i++)
    {                                                      // 注意，这里有问题！！！
        cout << "test1.size():  " << test1.size() << endl; // test1.size（）一直在增长
        cout << "i:  " << i << endl;
        cout << "i < test1.size():  " << (i < test1.size()) << endl;
        cout << "test1[i]:  " << test1[i] << endl; // 就是这里，map并没有下标访问的功能，是通过key来访问value的，因为 test1{{3, 11}}，所以这里i！=3时，就一直不会有输出，<< 被当作左移运算符处理，直到i==3，而在这之前，一直在往test1里面添加元素，test1.size()一直在增加，循环也会一直进行下去
    }
    cout << "=============" << endl;
    map<int, int> test{{3, 2}, {1, 4}, {99, 5}}; // map自动按照key进行排序，
    // map无法直接获取key和value值，所以遍历最好的方式还是迭代器
    for (auto i = test.begin(); i != test.end(); i++)
    {
        cout << i->first << " " << i->second << endl;
    }
    cout << "=============" << endl;

    // sort算法有个限制，利用sort算法只能对序列容器进行排序，就是线性的（如vector，list，deque）。map是一个集合容器，它里面存储的元素是pair，但是它不是线性存储的（像红黑树），所以利用sort不能直接和map结合进行排序。
    // 所以map本身并不能对value进行排序，非要排序的话，将map转换为vector排序后再返回，或者将key和value反转，value变为key然后排序
    // sort(test.begin(), test.end(), compare);

    map<string, int> str_test{{"he", 2}, {"helllo", 1}, {"hel", 11}}; // 如果key为string，则按照string长度进行排序
    for (auto i = str_test.begin(); i != str_test.end(); i++)
    {
        cout << i->first << " " << i->second << endl;
    }
    cout << "=============" << endl;

    map<int, string> test_str;
    for (auto i = str_test.begin(); i != str_test.end(); i++)
    {
        pair<int, string> temp = make_pair(i->second, i->first); // key和value互换
        test_str.insert(temp);                                   // 注意：这里不能用push_back,只有map[n].push_back(i)才能用
    }

    books physics{"physics", 25.8, 100};
    books math{"math", 23.8, 10};
    books philosophy{"philosophy", 3.8, 15};
    // map<books, int> test6{{math,3},{physics,1},{philosophy,11}};
    map<int, books> test6;
    // 注意：test6.insert(test6.begin(),({math, 3}, {physics, 4},{philosophy,0}));是错误的
    // test6.insert(test6.begin(),(make_pair(math, 3), make_pair(physics, 4),make_pair(philosophy,0)));

    test6.insert(pair<int, books>(3, math)); // 注意：不能让books在前面，因为map默认会对key排序，books在前面没法排序，会报错
    for (auto i = test6.begin(); i != test6.end(); i++)
    {
        cout << i->first << " " << i->second.name; // 输出 3 math
    }
    cout << endl;

    // 这里对结构的<运算符进行排序重载，让结构体满足排序要求，就可以把结构体放在前面了
    map<books, int> test7;
    test7.insert(pair<books, int>(math, 3));
    for (auto i = test7.begin(); i != test7.end(); i++)
    {
        cout << i->first.name << " " << i->second; // 输出 math 3
    }
}